﻿/**
<code>
  <author name="Zealic" email="zealic(at)gmail.com" type="Creator"/>
</code>
**/
using System;
using System.IO;


namespace Zealib.Extensions
{
    /// <summary>
    /// Extensions for <seealso cref="System.IO.Stream"/> class.
    /// </summary>
    public static class StreamExtensions
    {

        /// <summary>
        /// Save stream as file
        /// </summary>
        /// <param name="self">Strem for save</param>
        /// <param name="path">File path.</param>
        public static void SaveAsFile(this Stream self, string path)
        {
            self.IsNotNull();
            SaveAsFile(self,
                path,
                FileMode.CreateNew);
        }

        /// <summary>
        /// Save stream as file
        /// </summary>
        /// <param name="self">Strem for save</param>
        /// <param name="path">File path.</param>
        /// <param name="mode">File open mode.</param>
        public static void SaveAsFile(this Stream self, string path, FileMode mode)
        {
            self.IsNotNull();
            SaveAsFile(self,
                path,
                mode,
                (mode == FileMode.Append) ? FileAccess.Write : FileAccess.ReadWrite);
        }

        /// <summary>
        /// Save stream as file
        /// </summary>
        /// <param name="self">Strem for save</param>
        /// <param name="path">File path.</param>
        /// <param name="mode">File open mode.</param>
        /// <param name="access">Access mode</param>
        public static void SaveAsFile(this Stream self, string path, FileMode mode, FileAccess access)
        {
            self.IsNotNull();
            SaveAsFile(self,
                path,
                mode,
                access,
                FileShare.Read);
        }

        /// <summary>
        /// Save stream as file
        /// </summary>
        /// <param name="self">Strem for save</param>
        /// <param name="path">File path.</param>
        /// <param name="mode">File open mode.</param>
        /// <param name="access">Access mode</param>
        /// <param name="share">Share mode</param>
        public static void SaveAsFile(this Stream self, string path, FileMode mode, FileAccess access, FileShare share)
        {
            self.IsNotNull();
            SaveAsFile(self,
                path,
                mode,
                access,
                FileShare.Read,
                4096);
        }

        /// <summary>
        /// Save stream as file
        /// </summary>
        /// <param name="self">Strem for save</param>
        /// <param name="path">File path.</param>
        /// <param name="mode">File open mode.</param>
        /// <param name="access">Access mode</param>
        /// <param name="share">Share mode</param>
        /// <param name="bufferSize">Buffer size</param>
        public static void SaveAsFile(this Stream self, string path, FileMode mode, FileAccess access, FileShare share, int bufferSize)
        {
            self.IsNotNull();
            using (FileStream fs = new FileStream(path, mode, access, share, bufferSize))
            {
                int count = 0;
                byte[] buffer = new byte[4096];
                while ((count = self.Read(buffer, 0, buffer.Length)) != 0)
                {
                    fs.Write(buffer, 0, count);
                }
                fs.Flush();
            }
        }

    }
}
